package com.itown.expo.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.security.AuthenticationServiceException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;

import webframe.common.helper.FormatTransformHelper;
import webframe.common.helper.LogonLog;

import com.itown.expo.model.EntUserInfo;
import com.itown.expo.model.UserLoginInfo;
import com.itown.expo.model.UserRightSpec;
import com.itown.expo.model.UserRightsType;

public class UserService extends MyBaseService implements UserDetailsService {
	private static Log log = LogFactory.getLog(UserService.class);
	private PasswordEncoder passwordEncoder;

	public PasswordEncoder getPasswordEncoder() {
		return passwordEncoder;
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}

	// ciquser
	public UserLoginInfo findCIQUserById(Serializable id) {
		return getUserLoginInfoDao().get(id);
	}

	public UserLoginInfo findUserByCIQUserName(String username) {
		return getUserLoginInfoDao().findSingleByHql(
				"from UserLoginInfo t where t.username=?",
				new Object[] { username });
	}

	public List<UserLoginInfo> findCIQUserByUsername(String username) {
		return getUserLoginInfoDao().findByHql(
				"from UserLoginInfo t where t.username=?",
				new Object[] { username });
	}

	public UserLoginInfo saveCIQUser(UserLoginInfo newuser) {
		return getUserLoginInfoDao().save(newuser);
	}

	public void deleteCIQUser(Long id) {
		getUserLoginInfoDao().delete(id);
	}

	public UserLoginInfo updateCIQUser(UserLoginInfo user) {
		return getUserLoginInfoDao().merge(user);
	}

	public UserDetails loadUserByUsername(String userName)
			throws UsernameNotFoundException, DataAccessException {
		String username = FormatTransformHelper.transEncodingFormBrowser(
				userName, "utf-8");
		UserLoginInfo user = findUserByCIQUserName(username);
		if (user == null) {
			log.info("用户名或密码错误 username=\"" + username + "\"");
			AuthenticationServiceException ex = new AuthenticationServiceException(
					"用户名或密码错误");
			throw ex;
		}
		List<UserRightSpec> rights = findUserRightSpecByUserid(user.getId());
		getUserLoginInfoDao().getHibernateTemplate().getSessionFactory()
				.getCurrentSession().evict(user);
		List<GrantedAuthority> gas = new ArrayList<GrantedAuthority>();
		for (UserRightSpec userRightSpec : rights) {
			gas.add(new GrantedAuthorityImpl(userRightSpec.getRightCode()));
		}
		if (user.getUsername().equals("admin")) {
			gas.add(new GrantedAuthorityImpl("ROLE_USER"));
		}
		user.setAuthorities(gas.toArray(new GrantedAuthority[] {}));
		return user;
	}

	public List<UserRightSpec> findUserRightSpecByUserid(Long id) {
		return getUserRightSpecDao().findByHql(
				"from UserRightSpec t where t.userid=?", new Object[] { id });
	}

	public List<UserRightsType> findAllRightType() {
		List<UserRightsType> list = getUserRightsTypeDao()
				.findByHql(
						"from UserRightsType t where t.code <> 'ROLE_ADMIN' order by t.id");
		return list;
	}

	public List<UserRightSpec> findUserRightByUserid(Long id) {
		return getUserRightSpecDao().findByHql(
				"from UserRightSpec t where t.userid=? order by id",
				new Object[] { id });
	}

	public void updateUserRight(Long userid, String[] authoritys) {
		List<UserRightSpec> olds = findUserRightByUserid(userid);
		for (UserRightSpec userRightSpec : olds) {
			getUserRightSpecDao().delete(userRightSpec.getId());
		}
		for (String code : authoritys) {
			UserRightSpec right = new UserRightSpec();
			right.setUserid(userid);
			right.setRightCode(code);
			getUserRightSpecDao().save(right);
		}
	}

	// entuser
	public EntUserInfo findEntUserById(Serializable id) {
		return getEntUserInfoDao().get(id);
	}

	public EntUserInfo findEntUserByUsername(String username) {
		return getEntUserInfoDao().findSingleByHql(
				"from EntUserInfo t where t.username=?",
				new Object[] { username });
	}

	public List<EntUserInfo> findEntUserListByUsername(String username) {
		return getEntUserInfoDao().findByHql(
				"from EntUserInfo t where t.username=?",
				new Object[] { username });
	}

	public EntUserInfo saveEntUser(EntUserInfo newuser) {
		return getEntUserInfoDao().save(newuser);
	}

	public void deleteEntUser(Long id) {
		getEntUserInfoDao().delete(id);
	}

	public EntUserInfo updateEntUser(EntUserInfo user) {
		return getEntUserInfoDao().merge(user);
	}

	// other

	public void saveLogonLog(LogonLog log) {
		getLogonLogDao().save(log);
	}
}
